﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using AR.Drone.Data;
using AR.Drone.Data.Navigation;
using AR.Drone.Data.Navigation.Native;

namespace isDrone
{
    public class Telemetry
    {
        public List<NavigationData> Navigation;

          private ISDrone _drone;
          public Telemetry(ISDrone drone)
          {
              Navigation = new List<NavigationData>();
            _drone = drone;
            _drone.DroneClient.NavigationDataAcquired += Telemetrywork;
              _drone.DroneClient.NavigationPacketAcquired += OnNavigationPacketAcquired;

          }

        public void Save()
        {
            var xml = new XmlSerializer(typeof(List<NavigationData>));
            var stream = new FileStream(Guid.NewGuid()+".xml", FileMode.CreateNew, FileAccess.ReadWrite);
            xml.Serialize(stream, Navigation);
            stream.Close();
        }

        public void Load(string file)
        {
            if (File.Exists(file))
            {
                var xml = new XmlSerializer(typeof (List<NavigationData>));
                var stream = new FileStream(file, FileMode.Open, FileAccess.Read);
                 Navigation=(List<NavigationData>) xml.Deserialize(stream);
                stream.Close();
            }
        }

        public double getFlyTime()
        {
            double t = 0;
            var start = -1;
            for (var i = 0; i < Navigation.Count; i++)
            {
                if ((Navigation[i].State.HasFlag(NavigationState.Flying) || Navigation[i].State.HasFlag(NavigationState.Hovering)) && i < Navigation.Count-1)
                {
                    if (start < 0)
                        start = i;
                }
                else
                {
                    if (start >= 0)
                    {

                        t += (Navigation[i].DateTemi - Navigation[start].DateTemi).TotalSeconds;
                        //    ( Navigation[i].Time>>21)
                        //-(Navigation[start].Time >> 21);
                        start = -1;
                    }
                }
            }
            return t;
        }

        public double Time(uint time)
        {
            return (time >> 21);
        }

        public double getFlyProc()
        {
            double t = 0;
            var start = -1;
            for (var i = 0; i < Navigation.Count; i++)
            {
                if ((Navigation[i].State.HasFlag(NavigationState.Flying) || Navigation[i].State.HasFlag(NavigationState.Hovering)) && i < Navigation.Count - 1)
                {
                    if (start < 0)
                        start = i;
                }
                else
                {
                    if (start >= 0)
                    {

                        t += (Navigation[start].Battery.Percentage) - (Navigation[i].Battery.Percentage);
                        start = -1;
                    }
                }
            }
            return t;
        }


        public double ProcPerSec()
        {
            var p = getFlyProc();
            return p > 0 ? getFlyTime()/p : 0;
        }
        public double EndTime()
        {
            return Date != null ? Date.Battery.Percentage*ProcPerSec() : 0;
        }

        public double TotalTime()
        {
            return  ProcPerSec() *100;
        }

        private void Telemetrywork(NavigationData date)
        {
            Navigation.Add(date);
            if (NewTelemetry != null) NewTelemetry();
        }

        public  NavdataBag navdataBag;
        private void OnNavigationPacketAcquired(NavigationPacket packet)
        {
            if (packet.Data != null)
                NavdataBagParser.TryParse(ref packet, out navdataBag);
            if (NewNavdata != null) NewNavdata();
        }

        public NavigationData Date
        {
            get
            {
                return Navigation.Count > 0 ? Navigation.Last() : null;
            }
        }


        public event TelemetryHandler NewNavdata;
  

        public event TelemetryHandler NewTelemetry;
        public delegate void TelemetryHandler();
    }
}
